package com.wasion.pwportable.jsi;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;

import com.google.gson.Gson;
import com.wasion.core.util.ConvertInXBaseUtil;
import com.wasion.core.util.FrameFormatter;
import com.wasion.core.util.StringUtil;
import com.wasion.pwportable.activity.PwPortableActivity;
import com.wasion.pwportable.domain.po.Point;
import com.wasion.pwportable.protocol.Result;
import com.wasion.pwportable.protocol.p2.CurrSettingArea;
import com.wasion.pwportable.protocol.p2.FixedFrame;
import com.wasion.pwportable.protocol.p2.Iec104Parser;
import com.wasion.pwportable.protocol.p2.InfoObject;
import com.wasion.pwportable.protocol.p2.Parameter;
import com.wasion.pwportable.protocol.p2.TypeIndentityEnum;
import com.wasion.pwportable.protocol.p2.VariableFrame;
import com.wasion.pwportable.service.PullPointsService;
import com.wasion.pwportable.usb.F232DeviceManager;

public class DebugJSI {

	// 上下文
	private static Context context;

	// webview，浏览器窗口
	private static WebView webView;

	// 进度条Handler
	private Handler handler;

	// 下发帧
	private static String outFrame;

	// 接收帧
	private static String inFrame;

	//
	private static Result result = new Result();

	//
	private static List<Point> points = new ArrayList<Point>();

	private F232DeviceManager deviceManager;

	public DebugJSI(Context context) {
		this.context = context;
		this.webView = PwPortableActivity.getWebView();
		this.handler = PwPortableActivity.getHandler();
		this.deviceManager = F232DeviceManager.getInstance(context);
	}

	// 消息处理handler
	private static Handler msgHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {

			// 显示终端的上行报文
			webView.loadUrl("javascript:showInFrame('"
					+ FrameFormatter.format(inFrame) + "');");

			// 收到的帧 解析
			if (inFrame.length() > 0) {

				byte[] data = ConvertInXBaseUtil.hexString2ByteArray(inFrame);

				Iec104Parser parser = new Iec104Parser(data);
				FixedFrame fixedFrame = parser.getFixedFrame();
				VariableFrame variableFrame = parser.getVariableFrame();

				// 固定帧处理
				if (null != fixedFrame) {

				}

				// 可变帧处理
				if (null != variableFrame) {
					int ti = variableFrame.getTypeIdentity();
					// Google Gson
					Gson gson = new Gson();
					if (ti == TypeIndentityEnum.SETTING_AREA_RD.getValue()) { // 读当前定值区号
						CurrSettingArea currSettingArea = variableFrame
								.getCurrSettingArea();

						webView.loadUrl("javascript:sendReadSNCmdCallback("
								+ gson.toJson(currSettingArea) + ")");
					} else if (ti == TypeIndentityEnum.SETTING_AREA_WR
							.getValue()) { // 切换定值区号
						CurrSettingArea currSettingArea = variableFrame
								.getCurrSettingArea();

						webView.loadUrl("javascript:sendChangeSNCmdCallback("
								+ gson.toJson(currSettingArea) + ")");
					} else if (ti == TypeIndentityEnum.PARAMS_RD.getValue()) { // 读多个/全部参数和定值
						List<Parameter> parameters = variableFrame
								.getParameters();

						webView.loadUrl("javascript:sendReadParamsCmdCallback("
								+ gson.toJson(parameters) + ")");
					} else if (ti == TypeIndentityEnum.ALL_DATA_COLLECT_TI
							.getValue()) { // 总召唤
						int cause = variableFrame.getCause();
						if (7 == cause) {
							webView.loadUrl("javascript:showMsg('终端响应总召唤!');");
						} else if (10 == cause) {
							webView.loadUrl("javascript:showMsg('总召唤流程结束!');");
						}
					} else if (ti == TypeIndentityEnum.SINGLE_POINT_INFO_TI
							.getValue()
							|| ti == TypeIndentityEnum.DOUBLE_POINT_INFO_TI
									.getValue()
							|| ti == TypeIndentityEnum.SINGLE_POINT_INFO_TIMESTAMP_TI
									.getValue()
							|| ti == TypeIndentityEnum.DOUBLE_POINT_INFO_TIMESTAMP_TI
									.getValue()) { // 遥信
						List<InfoObject> infoObjects = variableFrame
								.getInfoObjs();
						for (InfoObject o : infoObjects) {
							for (Point p : points) {
								if (o.getAddr() == p.getPoint()) {
									o.setName(p.getName());
									break;
								}
							}
						}
						webView.loadUrl("javascript:YXCallback("
								+ gson.toJson(infoObjects) + ")");
					} else if (ti == TypeIndentityEnum.MEASURED_VAL_NORMALIZE_TI
							.getValue()
							|| ti == TypeIndentityEnum.MEASURED_VAL_FLOAT_TI
									.getValue()
							|| ti == TypeIndentityEnum.MEASURED_VAL_NORMALIZE_TIMESTAMP_TI
									.getValue()
							|| ti == TypeIndentityEnum.MEASURED_VAL_FLOAT_TIMESTAMP_TI
									.getValue()) { // 遥测
						try {
							List<InfoObject> infoObjects = variableFrame
									.getInfoObjs();
							for (InfoObject o : infoObjects) {
								for (Point p : points) {
									if (o.getAddr() == p.getPoint()) {
										o.setName(p.getName());
										break;
									}
								}
							}
							webView.loadUrl("javascript:YCCallback("
									+ gson.toJson(infoObjects) + ")");
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
				}
			}
		}
	};

	/**
	 * 
	 * @ClassName: SendAndReadThread
	 * @Description: 帧发送和接收线程，避免UI线程卡死的现象
	 * @author 高意
	 * @date 2014-9-19 下午3:22:51
	 * 
	 */
	private class SendAndReadThread implements Runnable {

		@Override
		public void run() {
			if (!StringUtil.isEmpty(outFrame)) {
				inFrame = deviceManager.sendAndRead(outFrame);

				// 模拟开始------------------------
				// try {
				// //Thread.sleep(1000);
				// } catch (InterruptedException e) {
				// e.printStackTrace();
				// }

				if (Integer.parseInt(outFrame.substring(12, 14), 16) == TypeIndentityEnum.SETTING_AREA_RD
						.getValue()) {
					inFrame = "681401000100C90107000100000000010001000A00";
					if (null != inFrame) {
						Message msg = msgHandler.obtainMessage();
						msgHandler.sendMessage(msg);
					}
				} else if (Integer.parseInt(outFrame.substring(12, 14), 16) == TypeIndentityEnum.SETTING_AREA_WR
						.getValue()) {
					inFrame = outFrame;
					inFrame = inFrame.substring(0, 4) + "03000300"
							+ inFrame.substring(12, 14) + "0700"
							+ inFrame.substring(18);
					if (null != inFrame) {
						Message msg = msgHandler.obtainMessage();
						msgHandler.sendMessage(msg);
					}
				} else if (Integer.parseInt(outFrame.substring(12, 14), 16) == TypeIndentityEnum.PARAMS_RD
						.getValue()) {
					inFrame = outFrame;
					inFrame = "68" + "1A" + "05000500CA" + "02"
							+ "070001000100" + "00" + "0188002004DEF737D5"
							+ "0288002D0223F0";
					if (null != inFrame) {
						Message msg = msgHandler.obtainMessage();
						msgHandler.sendMessage(msg);
					}
				} else if (Integer.parseInt(outFrame.substring(12, 14), 16) == TypeIndentityEnum.ALL_DATA_COLLECT_TI
						.getValue()) {

					// 召唤命令(激活确认)
					inFrame = "680E0200020064010700010000000014";
					if (null != inFrame) {
						Message msg = msgHandler.obtainMessage();
						msgHandler.sendMessage(msg);
					}

					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}

					// 测量值,归一化值(响应站总召唤)
					inFrame = "684904000200099414000100014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
					if (null != inFrame) {
						Message msg = msgHandler.obtainMessage();
						msgHandler.sendMessage(msg);
					}
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					// 测量值,归一化值(响应站总召唤)
					inFrame = "682806000200098914000100154000000000000000000000000000000000000000000000000000000000";
					if (null != inFrame) {
						Message msg = msgHandler.obtainMessage();
						msgHandler.sendMessage(msg);
					}
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}

					// 单点信息(响应站总召唤)
					inFrame = "68710800020001E41400010001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
					if (null != inFrame) {
						Message msg = msgHandler.obtainMessage();
						msgHandler.sendMessage(msg);
					}
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}

					// 单点信息(响应站总召唤)
					inFrame = "68150A0002000188140001006500000000000001010100";
					if (null != inFrame) {
						Message msg = msgHandler.obtainMessage();
						msgHandler.sendMessage(msg);
					}
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					// 召唤命令(激活终止)
					inFrame = "680E0C00020064010A00010000000014";
					if (null != inFrame) {
						Message msg = msgHandler.obtainMessage();
						msgHandler.sendMessage(msg);
					}
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				// End------------------------

				// if (null != inFrame) {
				// Message msg = msgHandler.obtainMessage();
				// msgHandler.sendMessage(msg);
				// }
			}
		}
	};

	/**
	 * 
	 * @Title: startSendAndReadThread
	 * @Description: 开启读写线程
	 * @param
	 * @return Result
	 * @throws
	 */
	public void startSendAndReadThread() {

		try {
			// 显示下行报文
			webView.loadUrl("javascript:showOutFrame('"
					+ FrameFormatter.format(outFrame) + "')");

			SendAndReadThread srThread = new SendAndReadThread();
			Thread thread = new Thread(srThread);
			thread.start();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 
	 * @Title: sendReadSNCmd
	 * @Description: 下发读取定值区号的指令
	 * @param
	 * @return
	 * @throws
	 */
	@JavascriptInterface
	public void sendReadSNCmd() {

		handler.post(new Runnable() {
			@Override
			public void run() {
				outFrame = "680E00000000C90106000100000000";
				startSendAndReadThread();
			}
		});
	}

	/**
	 * 
	 * @Title: sendChangeSNCmd
	 * @Description: 下发切换定值区号的指令
	 * @param
	 * @return
	 * @throws
	 */
	@JavascriptInterface
	public void sendChangeSNCmd(final String currSN) {

		handler.post(new Runnable() {
			@Override
			public void run() {
				String temp = ConvertInXBaseUtil.decimal2Hex(Integer
						.parseInt(currSN));
				for (int i = temp.length(); i < 4; i++) {
					temp += "0";
				}
				outFrame = "681002000200C80106000100000000" + temp;
				startSendAndReadThread();
			}
		});
	}

	/**
	 * 
	 * @Title: sendReadParamsCmd
	 * @Description: 下发读多个参数和定值的指令
	 * @param
	 * @return
	 * @throws
	 */
	@JavascriptInterface
	public void sendReadParamsCmd(final String currSN, final String infoAddrs) {

		handler.post(new Runnable() {
			@Override
			public void run() {

				int length = 10;
				String[] arr = infoAddrs.split(",");

				String infoStr = "";
				for (int i = 0; i < arr.length; i++) {
					String temp = arr[i];
					infoStr += (temp.substring(4) + temp.substring(2, 4) + "00");
				}

				String localCurrSN = currSN;
				for (int i = currSN.length(); i < 4; i++) {
					localCurrSN = "0" + currSN;
					localCurrSN = (localCurrSN.substring(2) + localCurrSN
							.substring(0, 2));
				}

				outFrame = "68"
						+ ConvertInXBaseUtil.decimal2Hex(arr.length * 3
								+ length) + "04000400CA"
						+ ConvertInXBaseUtil.decimal2Hex(arr.length)
						+ "06000100" + localCurrSN + infoStr;
				startSendAndReadThread();
			}
		});
	}

	/**
	 * 
	 * @Title: sendAllCollectCmd
	 * @Description: 下发总召的指令
	 * @param
	 * @return
	 * @throws
	 */
	@JavascriptInterface
	public void sendAllCollectCmd() {

		handler.post(new Runnable() {
			@Override
			public void run() {

				outFrame = "68" // 68H1字节
						+ "0E"// 报文长度L1字节
						+ "08000800"// 控制域C4字节
						+ "64"// 类型标识符TI1字节
						+ "00"// 可变帧长限定词VSQ1字节
						+ "0600"// 传送原因COT2字节
						+ "0100"// ASDU公共地2字节
						+ "000000"// 信息对象地址（=0）3字节
						+ "16";// 召唤限定词QOI1字节

				try {
					File file = new File(Environment
							.getExternalStorageDirectory() + "/points.xml");

					if (file.exists()) {
						InputStream inStream = new FileInputStream(file);
						points = PullPointsService.getPoints(inStream);
					}
					
					startSendAndReadThread();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

}
